/*
 * @file     g_trng.h
 * @brief    source file for setting trng
 *
 * Change Logs:
 * Date            Author             Version        Notes
 * 2022-05-06      wanghongwei         V1.0.0        Change the register configuration to 0x667F
 */


#include "g_trng.h"

/**
* @brief  init TRNG
* @param  none
* @retval none
*/
void G_TRNG_Init(void)
{
    NVIC_DisableIRQ(TRNG_IRQn);
    ANA_RNG->RNG_CTRL0.reg |= 0xFFC00000;
    ANA_RNG->RNG_CTRL1.reg = 0x87878787;

    MSYSCTRL->RNG_CTRL = 0;
    delay_ms(5);
    MSYSCTRL->RNG_CTRL = 0x067f;
    delay_ms(5);
    uint32_t couter = 0;
    //rng generation enable
    while((MSYSCTRL->RNG_CTRL & (1 << 28)) == 0)
    {
        couter++;
        delay_us(10);
        if((couter % 0x1000) ==0)
        {
            MSYSCTRL->RNG_CTRL = 0;
            delay_ms(5);
            MSYSCTRL->RNG_CTRL = 0x067f;
            delay_ms(5);
        }
    }
}

/**
 * @brief  get 128bit TRNG data
 * @param  rand[4]:128bit TRNG data out of buf
 * @retval 0:succeed  1:error
 */
void G_TRNG_Get(volatile unsigned long *rand)
{
    rand[0] = MSYSCTRL->RNG_DATA0.reg;
    rand[1] = MSYSCTRL->RNG_DATA1.reg;
    rand[2] = MSYSCTRL->RNG_DATA2.reg;
    rand[3] = MSYSCTRL->RNG_DATA3.reg;
}

uint8_t G_GetTRNGData_8bit(void)
{
	uint8_t tmp = 0;
	uint8_t timer = 0;
	while(1)
	{
		tmp = G_GetTRNGData() & 0xff;
		if((tmp != 0) && (tmp != 0xff))
		{
			break;
		}
		timer++;
        if(timer > 10)
        {
            break;
        }
	}
    return tmp;
}

int G_GetTRNGData(void)
{
    static uint32_t old_rng_data  = 0;
    uint32_t tmp = 0;
    uint32_t temp = 0;
    while (1)
    {
        tmp = MSYSCTRL->RNG_DATA0.reg;
        if ((tmp != old_rng_data) && (tmp != 0) && (tmp != 0xffffffff))
        {
            old_rng_data = tmp;
            break;
        }
        temp++;
        if(temp > 19200000)
        {
            tmp = 0;
            break;
        }
    }
    return  tmp;
}

void G_TRNG_DeInit(void)
{
    ANA_RNG->RNG_CTRL0.reg = 0;
}
